package com.uwlaser.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.config.FileProperties;
import com.uwlaser.domain.CraftScanRule;
import com.uwlaser.domain.CraftStepImg;
import com.uwlaser.exception.BadRequestException;
import com.uwlaser.service.mapper.CraftScanRuleMapper;
import com.uwlaser.service.mapper.CraftStepImgMapper;
import com.uwlaser.utils.FileUtil;
import com.uwlaser.utils.StringUtils;
import com.uwlaser.utils.enums.DictValueEnum;
import lombok.AllArgsConstructor;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.utils.ConvertUtil;
import com.uwlaser.utils.PageUtil;
import com.uwlaser.domain.CraftStepDetail;
import com.uwlaser.service.CraftStepDetailService;
import com.uwlaser.service.dto.CraftStepDetailDto;
import com.uwlaser.service.dto.CraftStepDetailQueryParam;
import com.uwlaser.service.mapper.CraftStepDetailMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = CraftStepDetailService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class CraftStepDetailServiceImpl extends CommonServiceImpl<CraftStepDetailMapper, CraftStepDetail> implements CraftStepDetailService {

    // private final RedisUtils redisUtils;
    private final CraftStepDetailMapper craftStepDetailMapper;

    private final CraftStepImgMapper craftStepImgMapper;

    private final CraftScanRuleMapper craftScanRuleMapper;

    private final FileProperties properties;

    @Override
    public PageInfo<CraftStepDetailDto> queryAll(CraftStepDetailQueryParam query, Pageable pageable) {
        IPage<CraftStepDetail> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<CraftStepDetail> page = craftStepDetailMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, CraftStepDetailDto.class);
    }

    @Override
    public List<CraftStepDetailDto> queryAll(CraftStepDetailQueryParam query){
        return ConvertUtil.convertList(craftStepDetailMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), CraftStepDetailDto.class);
    }

    @Override
    public CraftStepDetail getById(Integer id) {
        return craftStepDetailMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public CraftStepDetailDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), CraftStepDetailDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(CraftStepDetailDto resources) {
        CraftStepDetail entity = ConvertUtil.convert(resources, CraftStepDetail.class);
        return craftStepDetailMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(CraftStepDetailDto resources){
        CraftStepDetail entity = ConvertUtil.convert(resources, CraftStepDetail.class);
        int ret = craftStepDetailMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<Integer> ids){

        for (Integer id : ids) {
            CraftScanRule craftScanRule = new CraftScanRule();
            craftScanRule.setStepId(id);
            craftScanRuleMapper.delete(new QueryWrapper<>(craftScanRule));

            CraftStepImg craftStepImg = new CraftStepImg();
            craftStepImg.setStepId(id);
            CraftStepImg stepImg = craftStepImgMapper.selectOne(new QueryWrapper<>(craftStepImg));
            if(stepImg != null){
                FileUtil.del(stepImg.getServerPath());
            }
            craftStepImgMapper.delete(new QueryWrapper<>(craftStepImg));
        }
        return craftStepDetailMapper.deleteBatchIds(ids);
    }

    /**
     * 添加
     * @param multipartFile
     * @param resources
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CraftStepDetailDto insert(MultipartFile multipartFile, CraftStepDetailDto resources) {
        CraftStepDetail entity = ConvertUtil.convert(resources, CraftStepDetail.class);
        CraftStepDetail craftStepDetail = new CraftStepDetail();
        craftStepDetail.setStepCode(entity.getStepCode());
        craftStepDetail.setStepsId(entity.getStepsId());
        Integer integer = craftStepDetailMapper.selectCount(new QueryWrapper<>(craftStepDetail));
        if(integer > 0){
            throw new RuntimeException("工步编号【"+entity.getStepCode()+"】不能重复！");
        }
        craftStepDetailMapper.insert(entity);
        //处理规则
        resources.setCraftScanRule(saveScanRule(entity,resources.getCraftScanRule()));
        //处理图片
        if(multipartFile != null){
            resources.setCraftStepImg(saveImg(multipartFile,entity));
        }
        return resources;
    }

    /**
     * 更新
     * @param multipartFile
     * @param resources
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CraftStepDetailDto updateById(MultipartFile multipartFile, CraftStepDetailDto resources) {
        CraftStepDetail entity = ConvertUtil.convert(resources, CraftStepDetail.class);
        craftStepDetailMapper.updateById(entity);
        CraftStepDetail craftStepDetail = new CraftStepDetail();
        craftStepDetail.setStepCode(entity.getStepCode());
        craftStepDetail.setStepsId(entity.getStepsId());
        Integer integer = craftStepDetailMapper.selectCount(new QueryWrapper<>(craftStepDetail));
        if(integer >= 2){
            throw new RuntimeException("工步编号【"+entity.getStepCode()+"】不能重复！");
        }

        //处理规则
        CraftScanRule wrapper = new CraftScanRule();
        wrapper.setStepId(entity.getId());
        //删除
        craftScanRuleMapper.delete(new QueryWrapper<>(wrapper));
        //插入
        resources.setCraftScanRule(saveScanRule(entity,resources.getCraftScanRule()));

        //删除图片
        removeFile(resources.getCraftStepImg());

        //处理图片
        if(multipartFile != null){
            resources.setCraftStepImg(saveImg(multipartFile,entity));
        }

        return resources;
    }

    //删除图片
    private void removeFile(CraftStepImg craftStepImg) {
        if(craftStepImg == null || craftStepImg.getId() == null){
            return;
        }
        if(!StringUtils.isEmpty(craftStepImg.getVisitPath())){
            return;
        }
        if(StringUtils.isEmpty(craftStepImg.getServerPath())){
            return;
        }
        //删除
        craftStepImgMapper.deleteById(craftStepImg.getId());
        //删除文件
        FileUtil.del(craftStepImg.getServerPath());
    }

    /**
     * 保存规则
     * @param entity
     * @param craftScanRule
     * @return
     */
    public CraftScanRule saveScanRule (CraftStepDetail entity,CraftScanRule craftScanRule){

        if(craftScanRule == null){
            return craftScanRule;
        }

        if(StringUtils.isEmpty(craftScanRule.getRuleType())){
            return craftScanRule;
        }

        if(entity.getStepType().equals(DictValueEnum.STEP_TYPE_OTHER.getValue())){
            return craftScanRule;
        }

        if(entity.getStepType().equals(DictValueEnum.STEP_TYPE_SCREW.getValue())){
            return craftScanRule;
        }

        craftScanRule.setStepId(entity.getId());
        craftScanRuleMapper.insert(craftScanRule);

        return craftScanRule;
    }

    /**
     * 保存图片
     * @return
     */
    public CraftStepImg saveImg(MultipartFile multipartFile,CraftStepDetail entity){
        // 文件大小验证
        FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize());
        // 验证文件上传的格式
        String image = "gif jpg png jpeg";
        String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        if(fileType != null && !image.contains(fileType)){
            throw new BadRequestException("文件格式错误！, 仅支持 " + image +" 格式");
        }

        String filePath = "step\\";
        File file = FileUtil.upload(multipartFile, properties.getPath().getCraft() + filePath);

        CraftStepImg craftStepImg = new CraftStepImg();
        craftStepImg.setStepId(entity.getId());
        craftStepImg.setFileName(file.getName());
        craftStepImg.setOriginalFileName(multipartFile.getOriginalFilename());
        craftStepImg.setServerPath(Objects.requireNonNull(file).getPath());
        craftStepImg.setSuffix(fileType);
        craftStepImg.setVisitPath("craft\\" + filePath + file.getName());
        craftStepImgMapper.insert(craftStepImg);
        return craftStepImg;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Integer id){
        Set<Integer> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<CraftStepDetailDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (CraftStepDetailDto craftStepDetail : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("工步集合ID", craftStepDetail.getStepsId());
              map.put("工步顺序", craftStepDetail.getStepNo());
              map.put("工步编号", craftStepDetail.getStepCode());
              map.put("工步名称", craftStepDetail.getStepName());
              map.put("工步类型", craftStepDetail.getStepType());
              map.put("工步指示", craftStepDetail.getStepInstructions());
              map.put("是否校验", craftStepDetail.getIsCheck());
              map.put("物料编码", craftStepDetail.getMaterialCode());
              map.put("物料名称", craftStepDetail.getMaterialName());
              map.put("拧紧程序号", craftStepDetail.getProgram());
              map.put("拧紧套筒号", craftStepDetail.getSleeve());
              map.put("拧紧枪号", craftStepDetail.getTool());
              map.put("描述", craftStepDetail.getRemark());
              map.put("创建人", craftStepDetail.getCreateBy());
              map.put("创建时间", craftStepDetail.getCreateTime());
              map.put("更新人", craftStepDetail.getUpdateBy());
              map.put("更新时间", craftStepDetail.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/
}
